﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using suirui.ZhuMu.Model;
using suirui.ZhuMu.Entity;
using suirui.ZhuMu.Entity.Entities;
using suirui.ZhuMu.Services;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using suirui.ZhuMu.Common;
using IdentityModel;
using suirui.ZhuMu.WebCore;
using suirui.ZhuMu.Framework;

namespace suirui.ZhuMu.MJGames.Controllers
{
    public class LoginController : BaseController
    {
        private readonly ILoginService _LoginSerivce;
        private readonly IUserService _UserService;

        private string strToken { get; set; }

        public LoginController(ILoginService loginSerivce, IUserService userService)
        {
            this._LoginSerivce = loginSerivce ?? throw new ArgumentNullException(nameof(loginSerivce));
            this._UserService = userService ?? throw new ArgumentNullException(nameof(userService));
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="loginDto"></param>
        /// <returns></returns>
        [HttpPost]
        //[SignParamFilter]
        [AllowAnonymous]
        public async Task<LoginResult<User>> Login(LoginDTO loginDto)
        {
            if (string.IsNullOrWhiteSpace(loginDto.Email))
            {
                return new LoginResult<User>() { Code = ErrorCode.FormatError, Message = "瞩目账号不能为空" };
            }

            var result = await _LoginSerivce.Login(loginDto);
            var loginResult = new LoginResult<User>();

            if (result.Code == ErrorCode.Success && result.Data != null)
            {
                var user = loginResult.Data = result.Data;

                //strToken = TokenOperate.GenerateAccessToken(TokenOperate.GetClaims(user));

                //var refreshToken = TokenOperate.GenerateRefreshToken();
                //TokenValidate.CreateRefreshToken(refreshToken, user.UserId.ToString());

                //loginResult.AccessToken = strToken;
                //loginResult.RefreshToken = refreshToken;

                return loginResult;
            }
            return new LoginResult<User>() { Code = ErrorCode.ResultError, Message = result.Message };
        }

        /// <summary>
        /// 刷新Token
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        //[SignParamFilter]
        [AllowAnonymous]
        public async Task<ReturnLoginDto<Response>> RefreshToken([FromBody] Response request)
        {
            //TODO 参数校验
            var principal = TokenOperate.GetPrincipalFromAccessToken(request.accessToken);

            if (principal is null)
            {
                return new ReturnLoginDto<Response>() { Code = ErrorCode.DecryptError, Message = "AccessToken解析错误，请确保正确的AccessToken！" };
            }

            var id = principal.Claims.First(c => c.Type == JwtClaimTypes.Id)?.Value;

            if (string.IsNullOrEmpty(id))
            {
                return new ReturnLoginDto<Response>() { Code = ErrorCode.DecryptError, Message = "AccessToken解析错误，无法解析出JwtClaimTypes.Id！" };
            }
            var user = _UserService.GetUserById(long.Parse(id))?.Result?.Data;
            //var user = await context.User.Include(d => d.UserRefreshTokens).FirstOrDefaultAsync(d => d.Id == id);

            if (user is null)//|| user.UserRefreshTokens?.Count() <= 0
            {
                return new ReturnLoginDto<Response>() { Code = ErrorCode.DecryptError, Message = "AccessToken解析错误，无法根据该AccessToken找到相应的用户信息！" };
            }

            if (!TokenValidate.IsValidRefreshToken(request.refreshToken))
            {
                return new ReturnLoginDto<Response>() { Code = ErrorCode.Unauthorized, Message = "RefreshToken不存在或已过期,需重新登录！" };
            }

            TokenValidate.RemoveRefreshToken(request.refreshToken);
            var refreshToken = TokenOperate.GenerateRefreshToken();
            TokenValidate.CreateRefreshToken(refreshToken, id);

            return new ReturnLoginDto<Response>()
            {
                Code = ErrorCode.Success,
                Message = "Token获取成功！",
                AccessToken = TokenOperate.GenerateAccessToken(TokenOperate.GetClaims(user)),
                RefreshToken = refreshToken
            };
        }

        /// <summary>
        /// 获取服务器的当前时间戳
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public async Task<APIResult<long>> GetServerTimeSpan()
        {
            return new APIResult<long>()
            {
                Code = ErrorCode.Success,
                Message = "获取成功",
                Data = DateTimeHelper.DateTimeToTimeStamp(DateTime.Now)
            };
        }



        /// <summary>
        /// 设置Token过期
        /// </summary>
        [HttpPost]
        public async Task<APIResult> SetTokenExpire([FromBody] Response request)
        {
            string requestToken = HttpContext.Request.Headers["Authorization"];
            requestToken = requestToken?.Replace("Bearer ", "");
            TokenValidate.RemoveRefreshToken(request.refreshToken);

            HttpContext.Request.Headers["Authorization"] = "";
            //if (UserContext.Current.Token != requestToken) return responseContent.Error("Token已失效!");

            HttpContext.Response.Headers.Add("Token-Expired", "true");
            strToken = "";
            return new APIResult() { Code = ErrorCode.Success, Message = "设置完成！" };
            // todo
        }

    }
}
